import gtk
import gnomevfs
import nautilus

# register x-www-browser as default
import webbrowser
if webbrowser._iscommand('x-www-browser'):
    if not 'x-www-browser' in webbrowser._tryorder:
        webbrowser._tryorder.insert(0, 'x-www-browser')
    webbrowser.register('x-www-browser', None, webbrowser.GenericBrowser(
        "x-www-browser '%s' >/dev/null 2>&1 &"))

def get_operations(handle, result, op_data, data):
    try:
        rsrc, operations = op_data
        file, menu = data
        uri = gnomevfs.URI(file.get_uri())
        for op, sensitive in flatten(operations):
            cb = ActivateCallback(uri, file, [rsrc], op)
            item = nautilus.MenuItem('plone::%s' % op.getId(),
                                     op.getLabel(),
                                     op.getShortDescription())
            item.set_property('sensitive', sensitive)
            item.connect('activate', cb)
            menu.append(item)
    finally:
        # Always end the gtk mainloop, otherwise get_file_items
        # will get blocked forever.
        gtk.main_quit()

def open_cb(handle, exc, data):
    if exc is None:
        handle.control(operation='plone:operations',
                       operation_data=None,
                       callback=get_operations,
                       callback_data=data)
    else:
        gtk.main_quit()


def flatten(ops):
    retval = []
    for op in ops:
        if hasattr(op, 'getChildOperations'):
            retval.append((op, False))
            retval.extend(flatten(op.getChildOperations()))
        else:
            retval.append((op, True))
    return retval

class ActivateCallback:

    def __init__(self, uri, file, resources, operation):
        self.uri = uri
        self.file = file
        self.resources = resources
        self.operation = operation

    def __call__(self, menuitem):
        def func(exc, data, op=self.operation.operate,
                 context=None, file=self.file,
                 resources=self.resources):
            op(context, resources)
            file.invalidate_extension_info()
        gnomevfs.async.open(self.uri, callback=func)

class WorkflowExtension(nautilus.MenuProvider):

    def __init__(self):
        pass

    def get_file_items(self, window, files):
        if len(files) != 1:
            return

        file = files[0]

        # We're only going to put ourselves on objects that support
        # workflows. That means files in the plone:// namespace for
        # now.
        if file.get_uri_scheme() != 'plone':
            return

        menu = []
        handle = gnomevfs.async.open(
            file.get_uri(), callback=open_cb,
            data=(file, menu,))
        # Run the gtk mainloop to trigger the async operation,
        # otherwise it won't get run until we return.
        gtk.main()
        return menu
